#include "tributecenterpanel.h"

TributeCenterPanel::TributeCenterPanel(QWidget *parent,
                                       int make[],
                                       QVector<Poker*> & own_poker_v,
                                       QVector<Poker*> & other_poker_v,
                                       int *last_numer_v,
                                       int *next_number_v):
    GamePlayCenterPanel(parent,make,own_poker_v,other_poker_v,last_numer_v ,next_number_v)
{
    init();
}

//初始化
void TributeCenterPanel::init(){
    cd = new CountDown((QWidget *)this->parent());//初始化计时器
    init_rev_tribute();//初始化反贡
    init_tribute();
}

//进贡运行
void TributeCenterPanel::run_tribute(){
    //反贡
    rev_tribute_show();
    while(1){
        qApp->processEvents();
        if(isClickedRev || isClickedNoRev || isTimeOutRev){
            break;
        }
    }
    for (int i =0;i < 1000000;++i) {
        qApp->processEvents();
    }
    qDebug() << "反贡阶段结束";
    hide_rev_tribute();

    if(isSuccess){
        //如果反贡成功
        rev_tribute_success(player_type::MY);
        for (int i =0;i < 1000000;++i) {
            qApp->processEvents();
        }
    }else {
        //失败
        //关闭计时器和显示失败提示
        rev_tribute_failed();
        int result_x = choose_one_to_my(player_type::NEXT,{2});
        qDebug() << "获得一张牌：" << result_x;
        while(1) {
            qApp->processEvents();
        }
        //自己进贡最大一张
        int result = tribute(player_type::NEXT);
        qDebug() << result;
        //根据result挑选回贡牌
        choose_pokers(result);
        while(1){
            qApp->processEvents();
            if(isChoosePoker || isTimeOutChoose ){
                break;
            }
        }
        //根据回贡的牌显示到中央,等待下家选择
        gift_to_center(player_type::NEXT);
        //模拟等待服务器交互
        for (int i =0;i < 1000000;++i) {
            qApp->processEvents();
        }

        //假设需要选择一张
        int index =choose_poker[0];
        //将其送给下家
        center_poker_to_other(index,player_type::NEXT);
        while(1) {
            qApp->processEvents();
        }
    }
    emit this->state_end(play_state::TRIBUTE);
}



//初始化反贡阶段组件
void TributeCenterPanel::init_rev_tribute(){
    QWidget * parent = (QWidget *)this->parent();
    cd->setPos(QPoint(out_card_space.x()+out_card_space.width()/2-cd->getLCDWidth(),out_card_space.height()/2));
    cd->setTime(7);

    rev_tribute_label = new QLabel("等待反贡……",parent);//反贡提示标签
    rev_tribute_label->move(out_card_space.x()+out_card_space.width()/2,out_card_space.height()/2);
    rev_tribute_label->hide();

    rev_tribute_btn = new QPushButton("反贡",parent);//反贡按钮
    rev_tribute_btn->move(own_space.width()/2-rev_tribute_btn->width()-5,own_space.y()-20);
    rev_tribute_btn->hide();
    connect(rev_tribute_btn,&QPushButton::clicked,this,&TributeCenterPanel::clicked_rev_tribute_btn);

    no_rev_tribute_btn = new QPushButton("不反贡",parent);//不反贡按钮
    no_rev_tribute_btn->move(own_space.width()/2+no_rev_tribute_btn->width()+5,own_space.y()-20);
    no_rev_tribute_btn->hide();
    connect(no_rev_tribute_btn,&QPushButton::clicked,this,&TributeCenterPanel::clicked_norev_tribute_btn);

    rev_tribute_success_label = new QLabel("反贡成功:",parent);//反贡成功标签
    //rev_tribute_success_label->move(own_space.width()/2+no_rev_tribute_btn->width()+20,own_space.y()-20);
    rev_tribute_success_label->hide();
    isSuccess = false;
    isClickedRev = false;
    isClickedNoRev = false;
    isTimeOutRev = false;
}

//初始化进贡阶段组件
void TributeCenterPanel::init_tribute(){
    QWidget * parent = (QWidget *)this->parent();
    tribute_label = new QLabel("进贡阶段提示。。",parent);//进贡提示标签
    tribute_label->move(out_card_space.x()+out_card_space.width()/2,0);
    tribute_label->hide();

    out_poker = new QPushButton("给予别人",parent);//将牌给别人按钮
    out_poker->move(own_space.width()/2,own_space.y()-20);
    connect(out_poker,&QPushButton::clicked,this,&TributeCenterPanel::clicked_out_poker);
    out_poker->hide();

    choose_one_Poker = nullptr;

    isChoosePoker = false;
    isTimeOutChoose = false;

    //获取小于等于10的个数
    lower_equal_10_number = 0;
    foreach (Poker * poker, own_poker) {
        int index = poker->getIndex();
        if(index != 53 && index != 52 && index%13 <= 6){
            ++lower_equal_10_number;
        }
    }
}

//反贡阶段
//显示反贡阶段组件
void TributeCenterPanel::rev_tribute_show(){
    rev_tribute_label->show();
    int count_joker = 0;
    foreach (Poker * poker, own_poker) {
        if(poker->getIndex() == 52 || poker->getIndex() == 53){
            ++count_joker;
        }
    }
    //有两个王，显示 反贡按钮
    if(count_joker == 2){
        rev_tribute_btn->show();
        no_rev_tribute_btn->show();
    }
    //显示等待反贡
    rev_tribute_label->show();
    cd->start_time();//开启倒计时
    connect(cd,&CountDown::time_finish,this,&TributeCenterPanel::rev_tribute_timeout);
}

//隐藏反贡阶段组件
void TributeCenterPanel::hide_rev_tribute(){
    rev_tribute_label->hide();
    rev_tribute_btn->hide();
    no_rev_tribute_btn->hide();
    disconnect(cd,&CountDown::time_finish,this,&TributeCenterPanel::rev_tribute_timeout);
    cd->close_lcd_timer();
}

//根据玩家，显示成功反贡信息
void TributeCenterPanel::rev_tribute_success(player_type player){
    if(player == player_type::LAST){
        rev_tribute_success_label->move(out_card_space.x()+20,out_card_space.height()/2);
    }else if(player == player_type::MY){
        rev_tribute_success_label->move(out_card_space.x()+out_card_space.width()/2-20,out_card_space.height()/2);
    }else {
        rev_tribute_success_label->move(own_space.width()/2-rev_tribute_success_label->width()/2,own_space.y()-20);
    }
    rev_tribute_success_label->show();
}

//没有人反贡
void TributeCenterPanel::rev_tribute_failed(){
    hide_rev_tribute();
    //isSuccess = false;
}

//点击了反贡按钮
void TributeCenterPanel::clicked_rev_tribute_btn(){
    rev_tribute_btn->hide();
    no_rev_tribute_btn->hide();
    isClickedRev = true;
    isSuccess = true;
    qDebug() << "点击了反贡";
}

//点击了不反贡按钮
void TributeCenterPanel::clicked_norev_tribute_btn(){
    rev_tribute_btn->hide();
    no_rev_tribute_btn->hide();
    isClickedNoRev = true;
    isSuccess = false;
    qDebug() << "点击了不反贡";
}
//反贡时间到了
void TributeCenterPanel::rev_tribute_timeout(){
    rev_tribute_btn->hide();
    no_rev_tribute_btn->hide();
    isTimeOutRev = true;
    isSuccess = false;
    qDebug() << "反贡时间到了";
}

//进贡
//与自己相关的赠送和回赠
//将一张牌送到上下家, index为牌的序号
void TributeCenterPanel::center_poker_to_other(int index,player_type toPlayer){
    int poker_index = 0;
    foreach (Poker *poker, own_poker) {
        if(poker->getIndex() == index){
            break;
        }else{
            ++poker_index;
        }
    }
    //int index = own_poker[poker_index]->getIndex();
    //隐藏中央的牌
    foreach (Poker * poker, center_poker) {
        if(poker->getIndex() == index) poker->hide();
    }
    //将自己手牌中牌送个其他玩家
    //如果牌在整个区域左侧，那么比它小的全部右移，反之左移
    //自己隐藏
    own_poker[poker_index]->hide();
    if(own_poker[poker_index]->x() < this->own_space.width()/2){
        for(int i = 0;i < poker_index;++i){
            own_poker[i]->move(own_poker[i]->x()+STEP,own_poker[i]->y());
        }
    }else{
        for(int i = poker_index + 1;i < own_poker.size();++i){
            own_poker[i]->move(own_poker[i]->x()-STEP,own_poker[i]->y());
        }
    }
    //获取牌，然后删除
    Poker * need_move_poker = own_poker[poker_index];
    need_move_poker->setCanClick(false);
    own_poker.remove(poker_index);
    //根据toPlayer将need_move_poker调整到需要插入的地方
    int step = *(this->last_number);
    if(toPlayer == player_type::NEXT){
        step += *(this->next_number);
    }
    //停留再中间数秒
    need_move_poker->move(out_card_space.x()+out_card_space.width()/2,out_card_space.height()/2+200);
    need_move_poker->show();
    for (int i =0;i < 1000000;++i) {
        qApp->processEvents();
    }
    need_move_poker->hide();
    //修改位置，并切换贴图
    need_move_poker->move(other_poker[step-1]->x(),other_poker[step-1]->y()+STEP);
    need_move_poker->reset_Pixmap(54);
    //插入
    other_poker.insert(step,need_move_poker);
    //修改长度
    if(toPlayer == player_type::LAST){
        *(this->last_number) += 1;
    }else if(toPlayer == player_type::NEXT){
        *(this->next_number) += 1;
    }

    //展示
    need_move_poker->raise();
    need_move_poker->show();
    //隐藏所有中央区的牌
    foreach (Poker * poker, center_poker) {
        poker->hide();
    }
    //提示信息
    if(toPlayer == player_type::LAST)
        tribute_label->setText(QString("将%1给上家").arg(index));
    else {
        tribute_label->setText(QString("将%1给下家").arg(index));
    }
    tribute_label->show();

}


//将一张牌送给toPlayer，返回进贡的牌序号
int TributeCenterPanel::tribute(player_type toPlayer){
//    //复制最后的一张牌
//    int end = this->own_poker[this->own_poker.size() - 1]->getIndex();
//    Poker * poker = new Poker((QWidget *)this->parent(),end);
//    poker->hide();
    //取出一张牌

//    Poker * poker = this->own_poker[this->own_poker.size()];
//    this->own_poker.remove(this->own_poker.size() - 1);
//    poker->reset_Pixmap(54);
//    poker->hide();
    //找出一张需要最大但不是5的牌
    int i = 0;

    for(i = own_poker.size() - 1; i > 0;++i){
        //如果最大不为5，则取出
        if(own_poker[i]->getIndex() % 13 != 12) break;
    }
    int poker_index = i;
    int index = own_poker[poker_index]->getIndex();
    //如果牌在整个区域左侧，那么比它小的全部右移，反之左移
    //自己隐藏
    own_poker[poker_index]->hide();
    if(own_poker[poker_index]->x() < this->own_space.width()/2){
        for(int i = 0;i < poker_index;++i){
            own_poker[i]->move(own_poker[i]->x()+STEP,own_poker[i]->y());
        }
    }else{
        for(int i = poker_index + 1;i < own_poker.size();++i){
            own_poker[i]->move(own_poker[i]->x()-STEP,own_poker[i]->y());
        }
    }
    //获取牌，然后删除
    Poker * need_move_poker = own_poker[poker_index];
    need_move_poker->setCanClick(false);
    own_poker.remove(poker_index);
    //根据toPlayer将need_move_poker调整到需要插入的地方
    int step = *(this->last_number);
    if(toPlayer == player_type::NEXT){
        step += *(this->next_number);
    }


    //停留再中间数秒
    need_move_poker->move(out_card_space.x()+out_card_space.width()/2,out_card_space.height()/2+30);
    need_move_poker->show();
    for (int i =0;i < 1000000;++i) {
        qApp->processEvents();
    }
    need_move_poker->hide();
    //修改位置，并切换贴图
    need_move_poker->move(other_poker[step-1]->x(),other_poker[step-1]->y()+STEP);
    need_move_poker->reset_Pixmap(54);
    //插入
    other_poker.insert(step,need_move_poker);
    //修改长度
    if(toPlayer == player_type::LAST){
        *(this->last_number) += 1;
    }else if(toPlayer == player_type::NEXT){
        *(this->next_number) += 1;
    }

    //展示
    need_move_poker->raise();
    need_move_poker->show();
    //提示信息
    if(toPlayer == player_type::LAST)
        tribute_label->setText(QString("将%1给上家").arg(index));
    else {
        tribute_label->setText(QString("将%1给下家").arg(index));
    }
    tribute_label->show();
    return index;
}
//根据获得的牌，回赠
//用户选择牌，并选择回赠按钮，然后移动到中央，放入其他玩家，返回选择的牌
void TributeCenterPanel::choose_pokers(int index){
    //倒计时20s，时间到了触发
    cd->setTime(20);
    cd->setPos(QPoint(own_space.width()/2,own_space.y()-50));
    connect(cd,&CountDown::time_finish,this,&TributeCenterPanel::gift_timeout);

    //设置标签，提醒玩家选择几张
    switch(index){
        //大王
        case 53: need_out_number = 4; break;
        //小王
        case 52: need_out_number = 3; break;
        //2
        case 11:
        case 24:
        case 37:
        case 50: need_out_number = 2; break;
        //A
        case 10:
        case 23:
        case 36:
        case 49: need_out_number = 1; break;
    }
    tribute_label->setText(QString("需要你选择%1张牌小于等于10").arg(need_out_number));
    //给牌加上启动连接，这样点击牌就能让按钮显示
    add_poker_connection();
    //计时开始
    cd->start_time();
}

//选择赠送的时间到了
void TributeCenterPanel::gift_timeout(){
    //隐藏按钮
    out_poker->hide();
    //断开连接
    disconnect(cd,&CountDown::time_finish,this,&TributeCenterPanel::gift_timeout);
    isTimeOutChoose = true;
    //默认最小的need_out_number张牌
    auto it = own_poker.begin();
    for (int i = 0;i < need_out_number;++i) {
        own_out_poker.push_back(*it++);
    }
    //设置标签
    QString str = "";
    foreach (Poker * poker, own_out_poker) {
        str += QString::number(poker->getIndex());
        qDebug() << poker->getIndex();
        str.append(",");
        choose_poker.push_back(poker->getIndex());
    }
    tribute_label->setText(QString("时间到了,%1").arg(str));
    foreach (Poker * poker, this->own_poker) {
        disconnect(poker,&Poker::pos_changed,this,&TributeCenterPanel::add_out_poker);
    }
}
//点击回贡按钮
void TributeCenterPanel::clicked_out_poker(){
    //隐藏按钮
    out_poker->hide();
    //关闭倒计时
    cd->close_lcd_timer();
    disconnect(cd,&CountDown::time_finish,this,&TributeCenterPanel::gift_timeout);
    //设置标记
    isChoosePoker = true;
    //设置标签
    QString str = "";
    foreach (Poker * poker, own_out_poker) {
        str += QString::number(poker->getIndex());
        qDebug() << poker->getIndex();
        str.append(",");
        choose_poker.push_back(poker->getIndex());
    }
    tribute_label->setText(QString("回贡%1").arg(str));
    foreach (Poker * poker, this->own_poker) {
        disconnect(poker,&Poker::pos_changed,this,&TributeCenterPanel::add_out_poker);
    }
}

//给牌添加信号
void TributeCenterPanel::add_poker_connection(){

    //获取最小y坐标
    int min_y = own_poker[0]->y();
    bool isChange = false;
    foreach (Poker * poker, this->own_poker) {
        if(poker->y() < min_y){
            min_y = poker->y();
            isChange = true;
        }
    }
    //如果改变了
    if(isChange){
        //将突出的牌加入到own_out_poker
        qDebug() << "事先点起来的牌";
        foreach (Poker * poker, this->own_poker) {
            if(poker->y() == min_y){
                own_out_poker.push_back(poker);

                qDebug() << poker->getIndex();
            }
        }
        if(test_can_out())
            out_poker->show();
        else{
            out_poker->hide();
        }
    }

    //添加信号连接
    foreach (Poker * poker, this->own_poker) {
        connect(poker,&Poker::pos_changed,this,&TributeCenterPanel::add_out_poker);
    }
}

//添加一张牌到对应玩家序列出牌序列
void TributeCenterPanel::add_out_poker(bool isUp,Poker * poker){
    //如果牌上升了，就就将牌添加，否则删除
    if(isUp){
        qDebug() << "添加:" << poker;
        own_out_poker.push_back(poker);
//        foreach (const Poker * poker, own_out_poker) {
//           qDebug() << poker;
//        }
        if(test_can_out())
            out_poker->show();
        else{
            out_poker->hide();
        }

    }else {
        bool isOK = own_out_poker.removeOne(poker);
        if(isOK){
            qDebug() << "删除成功";
            if(test_can_out())
                out_poker->show();
            else{
                out_poker->hide();
            }
        }else{
            qDebug() << "删除失败";
            if(test_can_out())
                out_poker->show();
            else{
                out_poker->hide();
            }
        }
    }
}

bool TributeCenterPanel::test_can_out() const{
    if(need_out_number != own_out_poker.size()) return false;
    int out_poker_lower_equal_10_number = 0;
    foreach (Poker * poker, own_out_poker) {
        //判断小于等于10的个数
        int index = poker->getIndex();
        //如果出现大小王和5直接返回失败
        if(index == 53 || index == 52 || index % 13 == 12) return false;
        if(index != 53 && index != 52 && index%13 <= 6){
            ++out_poker_lower_equal_10_number;
        }

    }
    //如果小于等于10的个数和出牌序列中的一样多，那么证明全<=10
    if(out_poker_lower_equal_10_number == need_out_number){
        return true;
    }
    //如果小于等于10的个数==原本小于等于10的个数,那么其他的就可以给
    if(out_poker_lower_equal_10_number == lower_equal_10_number){
        return true;
    }
    return false;
}


//将选择的几张牌放入出牌区中间，等待选择
void TributeCenterPanel::gift_to_center(player_type toPlayer){
    //删除中间回贡区的牌
    if(!center_poker.isEmpty()){
        foreach (Poker * poker, center_poker) {
            delete poker;
        }
        center_poker.clear();
    }


    //复制出牌,并设置到中间
    int all_center_poker_width = choose_poker.size()*(own_poker[0]->width()+STEP) - STEP;
    int one_x = out_card_space.x()+(out_card_space.width()-all_center_poker_width)/2;
    int one_y = out_card_space.y()+(out_card_space.height()-own_poker[0]->width())/2;
    int i = 0;
    foreach (int index, choose_poker) {
        Poker * poker = new Poker((QWidget *)this->parent(),index);
        poker->move(one_x+i*(own_poker[0]->width()+STEP),one_y);
        poker->show();
        poker->raise();
        center_poker.push_back(poker);
        ++i;
    }
    //提示信息，开启倒计时
    cd->setTime(20);
    if(toPlayer == player_type::LAST){

        tribute_label->setText(QString("等待上家选择"));
        cd->setPos(QPoint(out_card_space.x(),out_card_space.height()/2));

    }else {
        tribute_label->setText(QString("等待下家选择"));
        cd->setPos(QPoint(out_card_space.x()+out_card_space.width(),out_card_space.height()/2));
    }

    cd->start_time();
}

//从回贡的牌中选一张，并加入牌中，返回选择的牌的序号
int TributeCenterPanel::choose_one_to_my(player_type sender,QVector<int> choose_poker){
    //开启选择框，获取想要选择的牌，并将其删除
    choose_one_Poker = new ChooseOnePoker((QWidget *)this->parent(),choose_poker);
    choose_one_Poker->exec();
    int result = choose_one_Poker->getResult();
    delete choose_one_Poker;
    choose_one_Poker = nullptr;
    Poker *poker = nullptr;
    //从sender取出一张牌
    if(sender == player_type::LAST){
        poker = other_poker[*this->last_number - 1];
        --(*this->last_number);
    }else if(sender == player_type::NEXT){
        poker = other_poker[*this->last_number + *this->next_number - 1];
        --(*this->next_number);
    }
    poker->reset_Pixmap(result);
    for (int i =0;i < 1000000;++i) {
        qApp->processEvents();
    }
    poker->move(out_card_space.x()+out_card_space.width()/2,out_card_space.height()/2+30);
    poker->show();
    for (int i =0;i < 1000000;++i) {
        qApp->processEvents();
    }

    poker->hide();
    other_poker.removeOne(poker);


    //将牌插入到牌中
    int i = 0;//i 为比当前值大的位置
    for (i = 0; i < own_poker.size();++i) {
        //如果需要插入的牌为大小王
        if(result >= 52){
            //且比当前值小，那么退出
            if(result < own_poker[i]->getIndex() ){
                break;
            }else{
                continue;
            }
        }
        if(result % 13 > own_poker[i]->getIndex() % 13){
            continue;
        }else if(result % 13 == own_poker[i]->getIndex() % 13){
            if(result < own_poker[i]->getIndex()){
                break;
            }
        }else if(result % 13 < own_poker[i]->getIndex() % 13 ){
            break;
        }

    }
    //如果有比它大位置，那么插入到它之前
    qDebug() << i;
    if(i < own_poker.size()){
        //位置和i重合
        poker->setCanClick(true);
        poker->move(own_poker[i]->pos());
        poker->raise();
        poker->show();
        //将所有牌移动
        for(;i < own_poker.size();++i) {
            own_poker[i]->move(own_poker[i]->x()+STEP,own_poker[i]->y());
            own_poker[i]->raise();
            own_poker[i]->show();
        }
        //poker插入集合
        own_poker.insert(i,poker);
    }else{
        //没有则尾插
        poker->setCanClick(true);
        //根据最后一张牌选位置
        poker->move(own_poker.back()->x()+STEP,own_poker.back()->y());
        poker->show();
        //poker尾插集合
        own_poker.push_back(poker);
    }
    if(sender == player_type::LAST)
        tribute_label->setText(QString("从上家获得了%1").arg(result));
    else {
        tribute_label->setText(QString("从下家获得了%1").arg(result));
    }
    tribute_label->show();
    return result;

}
